package com.shangguosha.core.event;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 事件总线 - 事件的发布和订阅中心
 */
public class EventBus {
    private static final Logger log = LoggerFactory.getLogger(EventBus.class);
    
    private final Map<String, List<EventListener<?>>> listeners = new ConcurrentHashMap<>();
    
    /**
     * 订阅事件
     */
    @SuppressWarnings("unchecked")
    public <T extends GameEvent> void subscribe(String eventType, EventListener<T> listener) {
        listeners.computeIfAbsent(eventType, k -> new ArrayList<>()).add(listener);
        log.debug("订阅事件: {} -> {}", eventType, listener.getClass().getSimpleName());
    }
    
    /**
     * 发布事件
     */
    @SuppressWarnings("unchecked")
    public void publish(GameEvent event) {
        List<EventListener<?>> eventListeners = listeners.get(event.getEventType());
        if (eventListeners != null) {
            log.debug("发布事件: {}, 监听器数量: {}", event.getEventType(), eventListeners.size());
            for (EventListener listener : eventListeners) {
                try {
                    listener.onEvent(event);
                } catch (Exception e) {
                    // 记录异常但不中断其他监听器
                    log.error("事件监听器执行异常: " + event.getEventType(), e);
                }
            }
        } else {
            log.debug("没有找到事件监听器: {}", event.getEventType());
        }
    }
    
    /**
     * 取消订阅
     */
    public void unsubscribe(String eventType, EventListener<?> listener) {
        List<EventListener<?>> eventListeners = listeners.get(eventType);
        if (eventListeners != null) {
            eventListeners.remove(listener);
            log.debug("取消订阅事件: {} -> {}", eventType, listener.getClass().getSimpleName());
        }
    }
    
    /**
     * 清空所有监听器
     */
    public void clear() {
        listeners.clear();
        log.debug("清空所有事件监听器");
    }
    
    /**
     * 获取事件类型的监听器数量
     */
    public int getListenerCount(String eventType) {
        List<EventListener<?>> eventListeners = listeners.get(eventType);
        return eventListeners != null ? eventListeners.size() : 0;
    }
}